﻿using Pool;
using Spine;
using Spine.Unity;
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;


public class RoleShowWidget : BaseDisplayWidget, IDispose
{
    public RoleData inspectorData;

    [Button("Reset", "refreshRoleData")]
    public int refreshRole;

    public static void CalledFunc(System.Object target, string strFuncName)
    {
        //找脚本上的FR函数，编辑器调用
        MethodInfo methodInfo = target.GetType()
                                      .GetMethod(strFuncName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
        if (methodInfo == null)
        {
            return;
        }
        methodInfo.Invoke(target, null);
    }

    public void refreshRoleData()
    {
        agent.RoleData = inspectorData;
        agent.refresh();
    }

    private BaseEntity agent;
    private string resName;
    private MeshRenderer render;
    public MeshRenderer Render
    {
        get
        {
            return render;
        }
        set
        {
            this.render = value;
        }
    }

    //动画相关
    private SkeletonAnimation skeletonAnimation;
    private string currAnim = "";
    private bool AnimEventCompleteFlag = false;

    public void setAgent(BaseEntity agent)
    {
        this.agent = agent;
        this.inspectorData = agent.RoleData;
        orgScale = new Vector3(agent.RoleData.scale.x, agent.RoleData.scale.y, agent.RoleData.scale.z);
    }

    public override void updateRenderOrder()
    {
        if (this.Render != null)
        {
            float y = agent.DyBox.centerY - this.agent.DyBox.centerZ;
            int order = y > 0 ? maxOrder - Mathf.CeilToInt(y * magnifyOrder) : maxOrder + Mathf.CeilToInt(y * magnifyOrder) * -1;
            this.Render.sortingOrder = order;
        }
    }

    /// <summary>
    /// 接口 播放动画
    /// </summary>
    /// <param name="anim"></param>
    /// <param name="loop"></param>
    /// <param name="add"></param>
    public float playAnim(string anim, bool loop = false, string add = null, bool forcePlay = false)
    {
        float delay = 0;
        if (!forcePlay && currAnim == anim) return delay;
        currAnim = anim;
        if (this.skeletonAnimation == null) return 0;
        var animationState = skeletonAnimation.AnimationState;
        TrackEntry entry = animationState.SetAnimation(0, anim, loop);
        if (!string.IsNullOrEmpty(add))
        {
            delay = entry.AnimationTime;
            animationState.AddAnimation(0, add, true, delay);            
        }
        return delay;
    }
    //public delegate void TrackEntryDelegate(TrackEntry trackEntry);
    private void onAnimStart(TrackEntry trackEntry)
    {
        currAnim = trackEntry.Animation.Name;
    }

    /// <summary>
    /// 修改动画完成订阅
    /// </summary>
    /// <param name="isAdd"></param>
    public void modifyCompleteEvent(bool isAdd)
    {
        if (AnimEventCompleteFlag == isAdd) return;
        AnimEventCompleteFlag = isAdd;
        if (isAdd)
        {
            skeletonAnimation.AnimationState.Complete += onAnimComplete;
        }
        else
        {
            skeletonAnimation.AnimationState.Complete -= onAnimComplete;
        }
    }

    private void onAnimComplete(TrackEntry trackEntry)
    {
        if (this.agent.moveDir != TwlPhy.Vector2.zero)
        {
            agent.transFsm(FSM_Flag.Run);
        }
        else
        {
            agent.transFsm(FSM_Flag.Idle);
        }
    }

    protected override void loadFinish()
    {
        this.render = this.Prefab.GetComponent<MeshRenderer>();
        skeletonAnimation = this.Prefab.GetComponent<SkeletonAnimation>();
        skeletonAnimation.AnimationState.Start += onAnimStart;
        //播放一个动画就行了
        agent.transFsm(agent.Flag, null, true);
        changeLookFlag(this.agent.lookFlag);
    }

    public void changeLookFlag(LookFlag flag)
    {
        int val = flag == LookFlag.Right ? 1 : -1;
        orgScale.x = Mathf.Abs(orgScale.x) * val;
        if (this.Prefab != null)
        {
            this.Prefab.transform.localScale = orgScale;
        }
    }

    protected override void onStart()
    {
        refresh();
#if UNITY_EDITOR
        showInspector();
#endif
    }


    protected Vector3 orgScale = Vector3.zero;
    /// <summary>
    /// 实体表现刷新
    /// 1 model
    /// </summary>
    public override void refresh()
    {
        orgScale = new Vector3(agent.RoleData.scale.x, agent.RoleData.scale.y, agent.RoleData.scale.z);
        doMove();
        changeLookFlag(agent.lookFlag);
        loadModel(this.agent.RoleData.resName);
    }

    private Vector3 rolePos = Vector3.zero;
    public void doMove()
    {
        rolePos.x = agent.DyBox.centerX;
        rolePos.y = agent.DyBox.centerY + agent.DyBox.centerZ;
        this.Trans.position = rolePos;
    }

    //检视面板显示
    private InspectorWidget inspectorWidget;
    void showInspector()
    {
        inspectorWidget = this.gameObject.AddComponent<InspectorWidget>();
        inspectorWidget.fsmFlag = this.agent.Flag;
    }
    public void updateInspector()
    {
        if (inspectorWidget != null)
        {
            inspectorWidget.fsmFlag = this.agent.Flag;
        }
    }

#if Show_Gizmos
    /// <summary>
    /// Scene绘制碰撞器大小
    /// </summary>
    void OnDrawGizmos()
    {
        //绘制移动碰撞盒 碰撞使用XY轴
        Gizmos.color = Color.blue;
        Vector3 top = new Vector3(agent.DyBox.Left, agent.DyBox.Top+agent.DyBox.centerZ);
        Vector3 bottom = new Vector3(agent.DyBox.Right, agent.DyBox.Bottom + agent.DyBox.centerZ);
        Vector3 left = new Vector3(agent.DyBox.Left, agent.DyBox.Bottom + agent.DyBox.centerZ);
        Vector3 right = new Vector3(agent.DyBox.Right, agent.DyBox.Top + agent.DyBox.centerZ);
        Gizmos.DrawLine(top, left);
        Gizmos.DrawLine(left, bottom);
        Gizmos.DrawLine(bottom, right);
        Gizmos.DrawLine(right, top);
        //绘制受伤碰撞盒

        Vector3 top1 = new Vector3(agent.HitBox.Left , agent.HitBox.MaxH+agent.HitBox.centerY);
        Vector3 bottom1 = new Vector3(agent.HitBox.Right , agent.HitBox.MinH + agent.HitBox.centerY);
        Vector3 left1 = new Vector3(agent.HitBox.Left, agent.HitBox.MinH + agent.HitBox.centerY);
        Vector3 right1 = new Vector3(agent.HitBox.Right, agent.HitBox.MaxH + agent.HitBox.centerY);
        Gizmos.color = Color.green;
        Gizmos.DrawLine(top1, left1);
        Gizmos.DrawLine(left1, bottom1);
        Gizmos.DrawLine(bottom1, right1);
        Gizmos.DrawLine(right1, top1);
    }
#endif
}

